#define WIN32_LEAN_AND_MEAN

#include "../master.h"
#include <wininet.h>
#include <commctrl.h>
#include <shlwapi.h>
#include <stdio.h>
#include <stdlib.h>
#include "AudioSE.h"
#include "../comfunct/comfunct.h"

HWND hAudioPlayer = NULL;
bool bStopDownloading = false;

BOOL APIENTRY DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
     switch(dwReason)
     {
         case DLL_PROCESS_ATTACH:
         {
              hAudioPlayer = FindWindow(TEXT("AudioPlayer"), TEXT("AudioPlayer"));
         }
         break;
     }
	 return TRUE;
}

AUDIOSE_EXPORT DWORD WINAPI ASEThread(LPVOID lpParams)
{     
     LPTSTR lpszUrl = NULL, szAudioFile = NULL;
	 HANDLE hMemMap = NULL;
	 size_t s_tUrlLen = (size_t)lpParams;
     
     hMemMap = OpenFileMapping(FILE_MAP_ALL_ACCESS, false, TEXT("URLMap"));
     if(hMemMap == NULL)
     {
          ErrorInfo();
          ErrorMessage(GetLocalText(80));
          return 1;
     }
     lpszUrl = (LPTSTR)MapViewOfFile(hMemMap, FILE_MAP_ALL_ACCESS, 0, 0, s_tUrlLen);
     if(lpszUrl == NULL)
     {
          ErrorInfo();
          ErrorMessage(GetLocalText(81));
		  return 1;
     }
	 SendMessage(hAudioPlayer, WM_FREEMEMMAP, 0, 0);
	 szAudioFile = CreateTemp(lpszUrl);
	 if(szAudioFile != NULL)
	 {
		 PostMessage(hAudioPlayer, WM_FILEREADY, 0, (LPARAM)szAudioFile);
	 }
     UnmapViewOfFile(lpszUrl);
     CloseHandle(hMemMap);
     PostMessage(hAudioPlayer, WM_ASETHREADFINISHED, 0, 0);
	 free(szAudioFile);
     return 0;
}

bool FromInetToTemp(LPTSTR szUrl, HANDLE hTempAudio, LPTSTR szTempAudioFile)
{
     URL_COMPONENTS uc = {0};
     TCHAR* szHostName = NULL;
     TCHAR* szRequestedFile = NULL;
     TCHAR szWindowTextToSet[10] = TEXT("");
     LPTSTR szFile = NULL;
     HMENU hMenu = NULL, hSubMenu = NULL;
     bool bSuccess = false, bFinished = false;
     DWORD dwRemoteFileSize = 0, dwBytesDownloaded = 1, dwCount = 0, dwSize = 0;
     HINTERNET hInternetMaster = NULL, hInitConnection = NULL, hRequestParams = NULL;
     
	 hInternetMaster = ConnectHandle(TEXT("AudioPlayer"));
     if(hInternetMaster == NULL)
     {
         ErrorInfo();
         ErrorMessage(GetLocalText(82));
         return false;
     }
     
     szHostName = malloc(MAX_PATH * sizeof(TCHAR));
     szRequestedFile = malloc(MAX_PATH * sizeof(TCHAR));
     
	 uc.dwStructSize = sizeof(URL_COMPONENTS);
     uc.lpszHostName = szHostName;
     uc.dwHostNameLength = MAX_PATH;
     uc.lpszUrlPath = szRequestedFile;
     uc.dwUrlPathLength = MAX_PATH;
     
     InternetCrackUrl(szUrl, 0, ICU_ESCAPE, &uc);
     szFile = PathFindFileName(szRequestedFile);
     
     SetStatus(hAudioPlayer, IDI_STATUS, 0, GetLocalText(83));
     SetStatus(hAudioPlayer, IDI_STATUS, 1, szFile);
     
     hInitConnection = ServerConnect(hInternetMaster, szHostName);
     if(hInitConnection == NULL)
     {
         ErrorInfo();
         ErrorMessage(GetLocalText(84));
         InternetCloseHandle(hInternetMaster);
         return false;
     }
     
     hRequestParams = HttpOpenRequest(hInitConnection, TEXT("GET"), szRequestedFile, NULL, NULL, NULL,
                                                 INTERNET_FLAG_NO_COOKIES | INTERNET_FLAG_NO_UI | INTERNET_FLAG_RELOAD | INTERNET_FLAG_PRAGMA_NOCACHE, 0);
     if(hRequestParams == NULL)
     {
         ErrorInfo();
         ErrorMessage(GetLocalText(84));
         InternetCloseHandle(hRequestParams);
         InternetCloseHandle(hInitConnection);
         InternetCloseHandle(hInternetMaster);
         return false;
     }
     
     bSuccess = HttpSendRequest(hRequestParams, NULL, 0L, NULL, 0);
     if(bSuccess == false)
     {
         ErrorInfo();
         ErrorMessage(GetLocalText(85));
         ASECleanup(hRequestParams, hInitConnection, hInternetMaster, szHostName, szRequestedFile);
         return false;
     }
     
     dwSize = sizeof(dwRemoteFileSize);
     
     HttpQueryInfo(hRequestParams, HTTP_QUERY_CONTENT_LENGTH | HTTP_QUERY_FLAG_NUMBER, (LPVOID)&dwRemoteFileSize, &dwSize, NULL);
     
     _sntprintf(szWindowTextToSet, 10, TEXT("%d"), dwRemoteFileSize);
     ShowWindow(GetDlgItem(hAudioPlayer, IDI_DIVIDE), SW_SHOW);
     SetDlgItemText(hAudioPlayer, IDI_TOTAL_TIME, szWindowTextToSet);
          
     do{
           BYTE* byDataAvailable = NULL;
           TCHAR* szFileSize = NULL;
           DWORD dwDataAvailable = 0, dwDownloadedSize = 0, dwBytesWritten = 0;
           bool bWriteSuccess;
           
           InternetQueryDataAvailable(hRequestParams, &dwDataAvailable, 0, 0);

           if(dwDataAvailable == 0)
           {
                bFinished = true;
           }
           
           if(bStopDownloading == true)
           {
                ASECleanup(hInternetMaster, hInitConnection, hRequestParams, szHostName, szRequestedFile);
                DeleteFile(szTempAudioFile);
				CloseHandle(hTempAudio);
                return false;
           }
           
           byDataAvailable = malloc(dwDataAvailable);
           
		   dwBytesDownloaded = 1;
		   dwCount = 0;

           while(dwBytesDownloaded != 0) 
           { 
			   if(!InternetReadFile(hRequestParams, &byDataAvailable[dwCount], dwDataAvailable - dwCount, &dwBytesDownloaded))
			   {
				   ErrorInfo();
                   ErrorMessage(GetLocalText(86));
                   ASECleanup(hInternetMaster, hInitConnection, hRequestParams, szHostName, szRequestedFile);
                   return false;
               }
               dwCount += dwBytesDownloaded;
           }
           SetEndOfFile(hTempAudio);
           bWriteSuccess = false;
           bWriteSuccess = WriteFile(hTempAudio, byDataAvailable, dwDataAvailable, &dwBytesWritten, NULL);
           if(bWriteSuccess == false)
           {
               ErrorInfo();
               ErrorMessage(GetLocalText(87));
               ASECleanup(hInternetMaster, hInitConnection, hRequestParams, szHostName, szRequestedFile);
               return false;
           }
           free(byDataAvailable);
           dwDownloadedSize = GetFileSize(hTempAudio, NULL);
           
           szFileSize = malloc(25 * sizeof(TCHAR));
           _sntprintf(szFileSize, 24, TEXT("%d"), dwDownloadedSize);
           SetDlgItemText(hAudioPlayer, IDI_ELAPSED_TIME, szFileSize);
           free(szFileSize);
                      
     } while (bFinished != true);
     
     hMenu = GetMenu(hAudioPlayer);
     hSubMenu = GetSubMenu(hMenu, FILE_MENU);
     EnableMenuItem(hSubMenu, IDI_FILE_SAVESTREAM, MF_BYCOMMAND | MF_ENABLED);
     DrawMenuBar(hAudioPlayer);
     
     ASECleanup(hInternetMaster, hInitConnection, hRequestParams, szHostName, szRequestedFile);
     
     return TRUE;
}

LPTSTR CreateTemp(LPTSTR szUrl)
{
     TCHAR szTempDir[MAX_PATH] = TEXT(""), szLocalFileName[MAX_PATH] = TEXT("");
	 TCHAR* szAudioFile = NULL;
     bool bDownload = false;
	 HANDLE hTempAudio = NULL;

     GetTempPath(MAX_PATH, szTempDir);
     if(!GetTempFileName(szTempDir, TEXT("apd"), 0, szLocalFileName))
     {
         ErrorInfo();
         return NULL;
     }
     hTempAudio = CreateFile(szLocalFileName, GENERIC_WRITE, FILE_SHARE_READ, NULL,
                              CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY, NULL);
     
     if(hTempAudio == NULL || hTempAudio == INVALID_HANDLE_VALUE)
     {
          ErrorInfo();
          return NULL;
     }
     bDownload = FromInetToTemp(szUrl, hTempAudio, szLocalFileName);
     if(bDownload == false)
     {
         SendMessage(hAudioPlayer, WM_CLOSESTREAM, 0, 0);
         return NULL;
     }
     szAudioFile = malloc(MAX_PATH * sizeof(TCHAR));
	 CopyMemory(szAudioFile, szLocalFileName, (MAX_PATH * sizeof(TCHAR)));
	 CloseHandle(hTempAudio);
     return szAudioFile;
}

AUDIOSE_EXPORT void StopDownloading(void)
{
    bStopDownloading = true;
    return;
}

void ASECleanup(HINTERNET hMaster, HINTERNET hConnection, HINTERNET hRequest, TCHAR* szHostName, TCHAR* szRequestedFile)
{
    InternetCloseHandle(hRequest);
    InternetCloseHandle(hConnection);
    InternetCloseHandle(hMaster);
    free(szHostName);
    free(szRequestedFile);
    return;
}
